using System;
using bbv.DomainDrivenDesign.Interfaces;

namespace O1.Social.Newsgator.Repository.LinqToSql
{
    public class Spec<TPoco, TDto> : ISpec<TPoco> //Base Spec with inner ISpecification (bbv) in DAL repo
    {
        public string Name { get; protected set; }
        internal ISpecification<TDto> InnerSpec { get; private set; }

        public Spec(ISpecification<TDto> innerSpec) : this(innerSpec, null) { }
        public Spec(ISpecification<TDto> innerSpec, string name)
        {
            Name = name ?? GetType().Name;
            InnerSpec = innerSpec;
        }

        public ISpec<TPoco> And(ISpec<TPoco> spec)
        {
            var baseSpec = spec as Spec<TPoco, TDto>;

            if (baseSpec != null)
            {
                return new Spec<TPoco, TDto>(InnerSpec.And(baseSpec.InnerSpec), Name + " AND " + baseSpec.Name);
            }
            throw new ArgumentException("spec");
        }
        public ISpec<TPoco> Or(ISpec<TPoco> spec)
        {
            var baseSpec = spec as Spec<TPoco, TDto>;

            if (baseSpec != null)
            {
                return new Spec<TPoco, TDto>(InnerSpec.Or(baseSpec.InnerSpec), Name + " OR " + baseSpec.Name);
            }
            throw new ArgumentException("spec");
        }
        public ISpec<TPoco> Not()
        {
            return new Spec<TPoco, TDto>(InnerSpec.Not(), "NOT " + Name);
        }
    }
}